package com.douqu.game.main.server.netty;


import com.alibaba.fastjson.JSONObject;
import com.bean.core.util.HttpJsonUtils;
import com.bean.core.util.TimeUtils;
import com.bean.core.util.Utils;
import com.douqu.game.core.config.AssetConfig;
import com.douqu.game.core.config.MailConfig;
import com.douqu.game.core.config.StableDataConfig;
import com.douqu.game.core.config.card.CardConfig;
import com.douqu.game.core.config.common.GoodsData;
import com.douqu.game.core.config.goods.PropConfig;
import com.douqu.game.core.config.mall.MallConfig;
import com.douqu.game.core.config.task.TaskConfig;
import com.douqu.game.core.controller.PlayerController;
import com.douqu.game.core.database.model.IllegalityModel;
import com.douqu.game.core.database.model.PlayerModel;
import com.douqu.game.core.database.model.UserModel;
import com.douqu.game.core.e.*;
import com.douqu.game.core.entity.Player;
import com.douqu.game.core.entity.battle.BattleInitParam;
import com.douqu.game.core.entity.battle.PlayerBattleData;
import com.douqu.game.core.entity.common.TwoTuple;
import com.douqu.game.core.entity.db.MailDB;
import com.douqu.game.core.entity.ext.BagInfo;
import com.douqu.game.core.entity.ext.MailInfo;
import com.douqu.game.core.factory.*;
import com.douqu.game.core.netty.NettyConnection;
import com.douqu.game.core.protobuf.*;
import com.douqu.game.core.protobuf.SGMainProto.E_MSG_ID;
import com.douqu.game.core.protobuf.SGMainProto.E_MSG_TYPE;
import com.douqu.game.core.util.*;
import com.douqu.game.main.GameServer;
import com.douqu.game.main.msg.*;
import com.douqu.game.main.server.*;
import com.douqu.game.main.server.entity.NoticeInfo;
import com.douqu.game.main.server.entity.WaitPlayer;
import com.douqu.game.main.service.PlayerService;
import com.douqu.game.main.util.MsgUtils;
import com.google.protobuf.InvalidProtocolBufferException;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * Created by bean on 2017/3/9.
 */
public class NettyTCPServerHandler extends ChannelInboundHandlerAdapter
{
    private NettyConnection connection;

    private SGCommonProto.E_CAMP_TYPE recommendCamp;

    /**
     * 是否是合服准备
     * 默认是false 可以进行正常的链接与通信
     * 当合服的时候设置成true 玩家不再可以进行任何登录操作与通信
     */
    private volatile static boolean isMerge = false;

    private void close()
    {
        LogUtils.info("客户端断开,类型 -> " + connection.getDestroyType() + " -> " + connection.getChannel().remoteAddress());
        if(connection.getDestroyType() != E_ConnectionDestroyType.SERVER_CLOSE)
        {
            Object object = connection.getObject();
            if(object != null)
            {
                if(object instanceof PlayerController)
                {
                    PlayerController playerController = (PlayerController) object;
                    if(playerController != null)
                    {
                        if (connection.getDestroyType() == E_ConnectionDestroyType.BATTLE_OFFLINE) {
                            //在战斗中，只断开连接，不删除数据
                            LogUtils.info("去战斗了,断开连接......................." + connection.getRemoteAddress() + " " + playerController.getName());
                            GameServer.getInstance().savePlayerSync(playerController.getPlayer());
                        } else {
                            LogUtils.info("普通模式断开连接......................." + connection.getRemoteAddress() + " " + playerController.getName());
                            GameServer.getInstance().playerOffline(playerController, false, E_OffLineType.OFFLINE_CLIENT_ACTIVE);
                        }
                    }
                }
            }
        }

        ServerManager.getInstance().removeServerInfo(connection);
        GameServer.getInstance().getWorldManager().removeConnection(connection);

        connection.destroy();
    }


    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception
    {
        if (IdleStateEvent.class.isAssignableFrom(evt.getClass())) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.READER_IDLE)
            {
                if(connection.getObject() == null)
                {
                    LogUtils.warn("null connection Reader Timeout!" + connection);

                    close();
                }
            }
        }
    }




    /*
      * channelAction
      *
      * 当客户端主动链接服务端的链接后，这个通道就是活跃的了。也就是客户端与服务端建立了通信通道并且可以传输数据
      *
      */
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        /**
         * 合服过程中 不允许任何用户登录
         */
        if(isMerge)
            return;

        LogUtils.info("Client Connect Success:" + ctx.channel().remoteAddress() + " ------ -  ");

        connection = new NettyConnection(ctx.channel(), DataFactory.currentTime);

        GameServer.getInstance().getWorldManager().addConnection(connection);

        LogUtils.debug("-----------" + connection.getId());
    }



    /*
     * channelInactive
     *
     *
     * 当客户端主动断开服务端的 链接后，这个通道就是不活跃的。也就是说客户端与服务端的关闭了通信通道并且不可以传输数据
     *
     */
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {

        LogUtils.info("Client Disconnect:" + connection.getRemoteAddress());

        if(connection.getObject() instanceof PlayerController)
        {

        }
        else if(connection.getObject() != null)
        {
            LogUtils.warn("连接断开  -> " + connection);
        }

        close();
    }


    /**
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg)
    {
        /**
         * 合服过程中断绝一切客户端消息
         */
        if (isMerge)
            return;

        if(LoadManager.loading || LoadManager.updating)
        {
            connection.sendWarn(WordFactory.SERVER_IS_LOADING);
            return;
        }

        if(StringUtils.isNullOrEmpty(GameServer.getInstance().getServerHost()))
        {
            connection.sendWarn(WordFactory.SERVER_IS_READY);
            return;
        }

        ByteBuf byteBuf = (ByteBuf) msg;
        try{
            int code = BufferUtils.readShort(byteBuf);

            if(code != E_MSG_ID.MsgID_System_Ping_VALUE)
            {
                LogUtils.debug("code -> " + E_MSG_ID.forNumber(code) + " -> " + code + " -> data length: " + byteBuf.readableBytes());
            }

            if(CodeFactory.isServer(code))
            {
                ServerMsgChannel.messageChannel(code, connection, byteBuf);
            }
            else
            {
                if(!GameServer.getInstance().isOpen())
                {
                    connection.sendWarn(WordFactory.SERVER_IS_MAINTAIN);
                    if(code == E_MSG_ID.MsgID_System_Login_VALUE)
                    {
                        MsgUtils.sendLoginFail(connection);
                    }
                    return;
                }

                IllegalityModel illegality = connection.receiveMsg(DataFactory.currentTime, code);

                if(E_MSG_ID.MsgID_System_Login_VALUE == code)
                {
                    //登录
                    login(byteBuf, ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress().getHostAddress());
                }
                else if(E_MSG_ID.MsgID_System_Logout_VALUE == code)
                {

//                    connection.sendUnknown();
//                    close();
                    connection.sendMsg(code);
                }
                else  if(E_MSG_ID.MsgID_System_MergeChoose_VALUE == code)
                {
                    //合区选择
                    mergeServer(connection, byteBuf);
                }
                else if(E_MSG_ID.MsgID_System_CancelWait_VALUE == code)
                {
                    //退出等待
                    cancelWait(byteBuf);
                }
                else if(E_MSG_ID.MsgID_System_Ping_VALUE == code)
                {
                    //ping 心跳
                }
                else if(E_MSG_ID.MsgID_System_Regist_VALUE == code)
                {
                    register(byteBuf, ((InetSocketAddress)ctx.channel().remoteAddress()).getAddress().getHostAddress());
                }
                else
                {
                    if(connection.getObject() == null)
                    {
                        LogUtils.error("非法请求 -> " + code + "--->" + E_MSG_ID.forNumber(code));
                        GameServer.getInstance().saveIllegality(illegality);
                        connection.sendUnknown();
                        return;
                    }

                    if(!(connection.getObject() instanceof PlayerController))
                    {
                        LogUtils.error("非法请求 -> " + code + "--->" + E_MSG_ID.forNumber(code));
                        GameServer.getInstance().saveIllegality(illegality);
                        connection.sendUnknown();
                        return;
                    }

                    PlayerController playerController = (PlayerController) connection.getObject();

                    LogUtils.debug("code -> " + E_MSG_ID.forNumber(code) + " -> " + code + " -> player -> " + playerController.getName() + " connection -> " + playerController.getTcpConnection());

                    playerController.setLastUpdate(DataFactory.currentTime, code, E_PlayerLastUpdate.CODE);

                    if(illegality != null) illegality.setPlayerIndex(playerController.getObjectIndex());
                    GameServer.getInstance().saveIllegality(illegality);

                    if(playerController.getPlayer().isDel)
                    {
                        //被封号了
                        playerController.sendWarn(WordFactory.LOCK_ACCOUNT);
                        return;
                    }
                    if(playerController.isBattling())
                    {
                        playerController.sendWarn(WordFactory.BATTLING_NOT_ALLOW);
                        return;
                    }

                    if(E_MSG_ID.MsgID_System_GMCmd_VALUE == code)
                    {
                        //cmd命令处理
                        cmd(playerController, CoreUtils.byteBufToBytes(byteBuf));
                        SendUtils.sendChangeData(code, playerController);
                    }
                    else
                    {
                        try {
                            int msgType = code - code%100;
                            byte[] data = CoreUtils.byteBufToBytes(byteBuf);

                            if(playerController.getStatus() == E_PlayerStatus.CAMP_BATTLE_MATCH_SUCCESS)
                            {
                                playerController.sendWarn("即将进入阵营战,请不要作其它操作!");
                                return;
                            }

                            //检测功能是否解锁
                            int functionId = isForbid(playerController.getPlayer(),code,data);
                            if(functionId != 0){
                                playerController.sendWarn(WordFactory.FUNCTION_NOT_OPEN, functionId);
                                return;
                            }

                            if(playerController.getPlayer().lock)
                            {
                                LogUtils.error("玩家被锁住 -> " + playerController.getName());
                                connection.sendUnknown();
                                return;
                            }

                            playerController.getPlayer().getChangeGoods().getLegionChainCacheMap().clear();

                            switch (msgType)
                            {
                                case E_MSG_TYPE.MsgType_Player_VALUE:
                                    SpringContext.getMessageChannel(PlayerMsgChannel.class).messageChannel(code, playerController, data);
                                    break;
                                case E_MSG_TYPE.MsgType_Bag_VALUE:
                                    SpringContext.getMessageChannel(BagMsgChannel.class).messageChannel(code, playerController, data);
                                    break;
                                case E_MSG_TYPE.MsgType_Task_VALUE:
                                    SpringContext.getMessageChannel(TaskMsgChannel.class).messageChannel(code, playerController, data);
                                    break;
                                case E_MSG_TYPE.MsgType_Instance_VALUE:
                                case E_MSG_TYPE.MsgType_Arena_VALUE:
                                case E_MSG_TYPE.MsgType_OfficialWar_VALUE:
                                case E_MSG_TYPE.MsgType_HeroTemple_VALUE:
                                case E_MSG_TYPE.MsgType_Expedition_VALUE:
                                case E_MSG_TYPE.MsgType_WorldBoss_VALUE:
                                    SpringContext.getMessageChannel(ChallengeMsgChannel.class).messageChannel(code, playerController, data);
                                    break;
                                case E_MSG_TYPE.MsgType_Altar_VALUE:
                                case E_MSG_TYPE.MsgType_Lottery_VALUE:
                                case E_MSG_TYPE.MsgType_Store_VALUE:
                                case E_MSG_TYPE.MsgType_Bonus_VALUE:
                                case E_MSG_TYPE.MsgType_Mall_VALUE://mall
                                case E_MSG_TYPE.MsgType_WorldAuction_VALUE:
                                    SpringContext.getMessageChannel(BoonMsgChannel.class).messageChannel(code, playerController, data);
                                    break;
                                case E_MSG_TYPE.MsgType_Mail_VALUE:
                                    SpringContext.getMessageChannel(MailMsgChannel.class).messageChannel(code, playerController, data);
                                    break;
                                case E_MSG_TYPE.MsgType_Major_VALUE:
                                    SpringContext.getMessageChannel(MajorMsgChannel.class).messageChannel(code, playerController, data);
                                    break;
                                case E_MSG_TYPE.MsgType_Activity_VALUE:
                                    SpringContext.getMessageChannel(ActivityMsgChannel.class).messageChannel(code, playerController, data);
                                    break;
                                case E_MSG_TYPE.MsgType_WorldMap_VALUE:
                                    SpringContext.getMessageChannel(MapMsgChannel.class).messageChannel(code, playerController, data);
                                    break;
                            }

                            MsgUtils.addPlayerGoodsChange(code, playerController);

                            List<String> notices = playerController.getPlayer().getChangeGoods().getNotices();
                            for(String content : notices)
                            {
                                if(!StringUtils.isNullOrEmpty(content)){
//                                GameServer.getInstance().getWorldManager().dispatchGet(content);
                                    GameServer.getInstance().getWorldManager().getGetNoticeList().add(new NoticeInfo(content));
                                    LogUtils.debug("全局通知：" + content);
                                }
                            }
                            playerController.getPlayer().getChangeGoods().clearNoticeList();

                            SendUtils.sendChangeData(code, playerController);

                            //SendUtils.sendFunctionData(playerController);

                            //TODO 红点提醒 > 0
                            playerController.getPlayer().sendReadPoint(playerController);
                            // 连锁通知
                            playerController.getPlayer().sendLegionChain(playerController);

                        } catch (Exception e) {
                            e.printStackTrace();
                            playerController.sendWarn(WordFactory.PARAM_ERROR);
                        }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            LogUtils.errorException(e);
            connection.sendWarn(WordFactory.SERVER_DATA_ERROR);
        }finally {
            byteBuf.release();
        }

    }

    /**
     * 合区
     * @param byteBuf
     */
    private void mergeServer(NettyConnection connection, ByteBuf byteBuf) {
        byte[] data = CoreUtils.byteBufToBytes(byteBuf);
        SGSystemProto.C2S_MergeChoose request = null;
        try {
            request =  SGSystemProto.C2S_MergeChoose.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }

        if(request == null){
            connection.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        //合区的时候要验证一些数据
        if (request.getServerRuleId() <= 0){
            LogUtils.error("数据异常,serverRuleID:" + request.getServerRuleId());
            connection.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
//        if (request.getServerType() == null ||
//                request.getServerType() == SGCommonProto.E_SERVER_TYPE.SERVER_TYPE_UNKNOW){
//            LogUtils.error("数据异常,serverType 为null或UNKON");
//            connection.sendWarn(WordFactory.PARAM_ERROR);
//            return;
//        }
//        if (request.getPlatformType() == null ||
//                request.getPlatformType() == SGCommonProto.E_PLATFORM_TYPE.PLATFORM_TYPE_UNKNOW)
//        {
//            LogUtils.error("数据异常,platform 为null或UNKON");
//            connection.sendWarn(WordFactory.PARAM_ERROR);
//            return;
//        }

        if (StringUtils.isNullOrEmpty(request.getClientVersion())){
            LogUtils.error("数据异常,clientVersion is null");
            connection.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        LogUtils.info("合区选择:" + request.toString() + ",合区列表:" + connection.getMergePlayers());
        String objectIndex = request.getObjectIndex();
        List<PlayerModel> mergePlayers = connection.getMergePlayers();
        if(mergePlayers == null || mergePlayers.size() < 2){
            connection.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        PlayerModel choosePlayer = null;
        for(PlayerModel model : mergePlayers){
            if(model.getObjectIndex().equals(objectIndex)){
                choosePlayer = model;
                break;
            }
        }
        if(choosePlayer == null){
            LogUtils.error("choosePlayer is null");
            connection.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        mergePlayers.remove(choosePlayer);
        //删除其他的表数据
        PlayerService playerService = SpringContext.getBean(PlayerService.class);
        if(!mergePlayers.isEmpty()){
//            playerService.deleteUser(model.getUid());
            playerService.deletePlayer(mergePlayers);
        }

        //通知认证服务器删除多的合区角色
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("serverId", GameServer.getInstance().getServerId());
        jsonObject.put("channel", choosePlayer.getChannel());
        jsonObject.put("account", choosePlayer.getAccount());
        jsonObject.put("level", choosePlayer.getLevel());
        jsonObject.put("playerName", choosePlayer.getName());
        jsonObject.put("avatar", choosePlayer.getAvatar());

        String url = GameServer.getInstance().getAuthServerHost() + HttpFactory.PLAYER_MERGE_SERVER;
        JSONObject result = HttpJsonUtils.httpPost(url, jsonObject);
        if(result == null)
        {
            LogUtils.error("MergeServer Notify Error -> url:" + url);
            connection.sendWarn(WordFactory.SERVER_DATA_ERROR);
            return;
        }

        Player player = new Player(choosePlayer);

        enterGame(null, player, SGCommonProto.E_CHANNEL_TYPE.forNumber(player.channel), SGCommonProto.E_LOGIN_TYPE.LOGIN_TYPE_DEFAULT,request.getServerRuleId(),request.getClientVersion());
    }

    /**
     * 退出等待队列
     * @param byteBuf
     */
    private void cancelWait(ByteBuf byteBuf) {
        byte[] data = CoreUtils.byteBufToBytes(byteBuf);
        SGSystemProto.C2S_CancelWait request = null;
        try {
            request =  SGSystemProto.C2S_CancelWait.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }

        if(request == null){
            connection.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        LogUtils.info("取消排队参数:" + request.toString());

        String account = request.getAccount().trim();
        if(StringUtils.isNullOrEmpty(account))
        {
            LogUtils.debug("账号为空!");
            connection.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        GameServer.getInstance().getWorldManager().cancelWaitQueue(account);
        connection.sendMsg(E_MSG_ID.MsgID_System_CancelWait_VALUE, SGSystemProto.S2C_CancelWait.newBuilder().setAccount(account).build().toByteArray());

    }

    /**
     * gm命令
     * @param playerController
     * @param data
     */
    private void cmd(PlayerController playerController, byte[] data)
    {
        if(!CodeFactory.TEST){
            return;
        }
        SGSystemProto.C2S_GMCmd request = null;
        try {
            request = SGSystemProto.C2S_GMCmd.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        if(request == null){
            playerController.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        String cmd = request.getCmd();
        if("hero".equals(cmd))
        {
            //startBattle之前检测战斗中的卡牌数量
            String rs = MsgUtils.checkBattleCardCount(playerController.getPlayer());
            if(!com.douqu.game.core.util.StringUtils.isNullOrEmpty(rs)){
                playerController.sendWarn(rs);
                return;
            }
            MsgUtils.startBattle(playerController, SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_HERO_TEMPLE, E_BattleDetailType.PVE_HERO_TEMPLE, "1", new BattleInitParam(1));
        }
        else if("reset".equals(cmd)){
            if(!playerController.getPlayer().getHeroTempleData().isChallengeTimesEnough()){
                playerController.getPlayer().getHeroTempleData().reset();
            }

            if(!playerController.getPlayer().getArenaData().isChallengeTimesEnough()){
                playerController.getPlayer().getArenaData().reset();
            }

            if(!playerController.getPlayer().getOfficialData().isChallengeTimesEnough()){
                playerController.getPlayer().getOfficialData().reset();
             }
        }else if("passLevel".equals(cmd)){

        }else if("code".equals(cmd)){

        }else if("super".equals(cmd)){
            BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
            List<CardConfig > cardConfigs = DataFactory.getInstance().getDataList(DataFactory.CARD_KEY);
            List<AssetConfig> assetConfigs = DataFactory.getInstance().getDataList(DataFactory.ASSET_KEY);
            List<PropConfig> propConfigs = DataFactory.getInstance().getDataList(DataFactory.PROP_KEY);

            List<GoodsData> goodsDataList = new ArrayList<>();
            for(CardConfig cardConfig : cardConfigs){
                goodsDataList.add(new GoodsData(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_CARDS_VALUE,
                        cardConfig.id, 10));
            }
            for(AssetConfig assetConfig : assetConfigs){
                goodsDataList.add(new GoodsData(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_ASSETS_VALUE,
                        assetConfig.id, 10000000));
            }
            for(PropConfig propConfig : propConfigs){
                goodsDataList.add(new GoodsData(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_PROPS_VALUE,
                        propConfig.id, 10000000));
            }
            GoodsData[] goodsDatas = new GoodsData[goodsDataList.size()];
            for(int i = 0; i < goodsDataList.size(); i++){
                goodsDatas[i] = goodsDataList.get(i);
            }
            bagInfo.addGoods(goodsDatas, null);


        } else {
            String[] strs = cmd.split(ConstantFactory.DIVISION);
            GoodsData [] goodsDatas = new GoodsData[strs.length];
            for(int i = 0; i < strs.length; i ++){
                goodsDatas[i] = new GoodsData(strs[i]);
            }
            BagInfo bagInfo = playerController.getPlayer().getExtInfo(BagInfo.class);
            bagInfo.addGoods(goodsDatas,null);
        }

    }

    /**
     * 登录
     * @param byteBuf
     */
    public void login(ByteBuf byteBuf, String ip)
    {
        if(connection.getObject() != null)
        {
            //重复登录
            connection.sendUnknown();
            return;
        }

        byte[] data = CoreUtils.byteBufToBytes(byteBuf);
        SGSystemProto.C2S_Login request = null;
        try {
            request =  SGSystemProto.C2S_Login.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }

        if(request == null){
            MsgUtils.sendLoginFail(connection);
            return;
        }
        LogUtils.info("登录参数:" + request.toString() + " -> " + connection.getChannel().remoteAddress());
        if(request.getLoginType() == SGCommonProto.E_LOGIN_TYPE.LOGIN_TYPE_UNKNOWN){
            LogUtils.error("登录错误，登录类型不正确");
            MsgUtils.sendLoginFail(connection);
            return;
        }

        String account = request.getAccount().trim();
        if(StringUtils.isNullOrEmpty(account))
        {
            LogUtils.debug("账号为空!");
            MsgUtils.sendLoginFail(connection);
            return;
        }
        String password = request.getPassword().trim();
        SGCommonProto.E_CHANNEL_TYPE channel = request.getChannel();
        Player player = null;
        PlayerController playerController = null;

        if(request.getLoginType() == SGCommonProto.E_LOGIN_TYPE.LOGIN_TYPE_BATTLE_BACK)
        {
            playerController = GameServer.getInstance().getWorldManager().getPlayerController(account);//战斗返回登录比较特殊,这里的account其实是playerIndex
            boolean isCache = false;
            if(playerController == null)
            {
                playerController = GameServer.getInstance().getWorldManager().getBattleCachePlayer(account);
                LogUtils.warn("客户端出现BUG,先把链接断开了,服务器容错处理,获取缓存数据 -> " + (playerController == null ? "数据为空" : playerController.getName()));
                isCache = true;
            }

            if(playerController != null && password.equals(playerController.getPlayer().getEncodeKey()))
            {
                player = playerController.getPlayer();
            }

            if(player == null)
            {
                LogUtils.error("登录异常 -> password:" + password + (playerController == null ?
                        "   playerController is null" : " key:" + playerController.getPlayer().getEncodeKey()));
                MsgUtils.sendLoginFail(connection, channel);
//                connection.sendOffline();
                return;
            }

            if(isCache)
                GameServer.getInstance().getWorldManager().removeBattleCachePlayer(account);
        }
        else
        {
            boolean isDefault = request.getLoginType() == SGCommonProto.E_LOGIN_TYPE.LOGIN_TYPE_DEFAULT;
            if(isDefault)
            {
                synchronized (NettyTCPServerHandler.class)
                {
                    WorldManager worldManager = GameServer.getInstance().getWorldManager();
                    WaitPlayer waitPlayer = worldManager.getWaitPlayer(account);
                    if(waitPlayer != null)
                    {
                        if(waitPlayer.isWaiting())
                        {
                            MsgUtils.sendLoginFail(connection, waitPlayer.getWaitTime());
                            return;
                        }
                        else
                        {
                            worldManager.removeWaitPlayer(waitPlayer.getAccount());
                        }
                    }
                    else
                    {

                        if(worldManager.isFull()){
                            MsgUtils.sendLoginFail(connection, SGCommonProto.E_LOGIN_RESULT.LOGIN_RESULT_SERVER_FULL, channel, recommendCamp);
                            return;
                        }

                        if(worldManager.isNeedQueueWait())
                        {
                            int waitTime = (worldManager.getWaitPlayerCount() + 1) * ConfigFactory.gmSetting.getPlayerWaitTime();
                            ByteBuf newBuf = Unpooled.buffer();
                            newBuf.writeBytes(data);
                            worldManager.addWaitPlayer(account, waitTime, this, newBuf);
                            LogUtils.debug("需要等待:" + account +", 时长:" + waitTime);
                            MsgUtils.sendLoginFail(connection, waitTime);
                            return;
                        }
                    }
                    worldManager.addCachePlayer();
                }
            }

            PlayerService playerService = SpringContext.getBean(PlayerService.class);

            playerController = GameServer.getInstance().getWorldManager().getPlayerControllerByAccount(CoreUtils.createAccount(account, request.getChannel()));
            if(playerController != null)
            {
                if(playerController.isBattling())
                {
                    //战斗中不允许再登陆
                    if(isDefault)
                    {
                        LogUtils.warn("战斗中不允许再登陆：" + playerController.getStatus());
                        GameServer.getInstance().getWorldManager().reduceCachePlayer();
                        connection.sendUnknown();
                        return;
                    }
                    else
                        ServerManager.getInstance().sendOffline(playerController);
                }

                if(playerController.getStatus() == E_PlayerStatus.BATTLE_OFFLINE)
                {
                    LogUtils.info("战斗中离线重新连接,要告诉客户端战斗服务器的地址!");
                    PlayerBattleData playerBattleData = playerController.getBattleData();
                    if(playerBattleData != null)
                    {
                        SGCommonProto.ServerInfo.Builder serverInfoData = SGCommonProto.ServerInfo.newBuilder();
                        serverInfoData.setHost(playerBattleData.getBattleServerHost());
                        serverInfoData.setPort(playerBattleData.getBattleServerPort());

                        SGCommonProto.BattleData.Builder battleData = SGCommonProto.BattleData.newBuilder();
                        battleData.setBattleId(playerBattleData.getBattleId());
                        battleData.setPlayerIndex(playerController.getObjectIndex());
                        battleData.setBattleServer(serverInfoData);

                        MsgUtils.sendLoginFailForBattle(connection, channel, battleData);
                    }
                    if(isDefault) GameServer.getInstance().getWorldManager().reduceCachePlayer();
                    return;
                }

                Player tempPlayer = playerController.getPlayer();

                playerController.sendMsg(E_MSG_ID.MsgID_System_LoginOtherPlace_VALUE, SGSystemProto.S2C_LoginOtherPlace.newBuilder().build().toByteArray());
                ServerManager.getInstance().sendOffline(playerController);

                GameServer.getInstance().getWorldManager().playerExitGame(playerController, E_OffLineType.OFFLINE_REPEAT_LOGIN);
                playerController = null;

                //从战斗服务器退出重新连接主服务器的玩家
                LogUtils.info("直接赋值在线玩家:" + tempPlayer);
                player = tempPlayer;
            }
            else
            {
                //普通登录的时候要验证一些数据

                if (request.getServerRuleId() <= 0)
                {
                    LogUtils.error("数据异常,serverRuleId:" + request.getServerRuleId());
                    MsgUtils.sendLoginFail(connection, SGCommonProto.E_LOGIN_RESULT.LOGIN_RESULT_FAIL, channel, recommendCamp);
                    return;
                }

                if (StringUtils.isNullOrEmpty(request.getClientVersion())){
                    LogUtils.error("数据异常,clientVersion is null");
                    MsgUtils.sendLoginFail(connection, SGCommonProto.E_LOGIN_RESULT.LOGIN_RESULT_CLIENT_VERSION_ERROE, channel, recommendCamp);
                    return;
                }
                String newAccount = PlatformFactory.auth(channel, account, password);
                if(Utils.isNullOrEmpty(newAccount))
                {
                    LogUtils.error("认证失败，或者密码错误 -> account:" + account + " password:" + password);
                    MsgUtils.sendLoginFail(connection, SGCommonProto.E_LOGIN_RESULT.LOGIN_RESULT_FAIL, channel, recommendCamp);
                    if(isDefault) GameServer.getInstance().getWorldManager().reduceCachePlayer();
                    return;
                }
                LogUtils.info("认证成功返回的账号->", newAccount);
                UserModel user = playerService.getUserByAccount(newAccount);
                if(user == null)
                {
                    //当是手机号登录需要 验证是否绑定了设备
                    if(request.getChannel() == SGCommonProto.E_CHANNEL_TYPE.CHANNEL_TYPE_PHONE){
                        //注册
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("account", account);
                        JSONObject result = HttpJsonUtils.httpPost(GameServer.getInstance().getAuthServerHost() + HttpFactory.PLAYER_GET_PHONE_BAND_DEVICE, jsonObject);
                        String resultCode = result.getString("code");
                        if(ReturnMessage.SUCCESS.getCode().equals(resultCode)) {//成功
                            String deviceId = result.getString("data");
                            user = playerService.getUserByAccount(deviceId);
                            if(!StringUtils.isNullOrEmpty(deviceId)){
                                if(user != null){
                                    playerService.updateAccount(CoreUtils.createAccount(account, channel), user.getId());
                                }
                            }
                        }

                    }
                    if(user == null){
                        LogUtils.info("用户不存在,告诉客户端要注册");
                        recommendCamp = playerService.getMinPlayerCountCampType();
                        MsgUtils.sendLoginFail(connection, SGCommonProto.E_LOGIN_RESULT.LOGIN_RESULT_ENREGIST, channel, recommendCamp);
                        if(isDefault) GameServer.getInstance().getWorldManager().reduceCachePlayer();
                        return;
                    }

                }
//                if(user.getId() != null && user.getId() == 0)
//                { //认证失败
//                    LogUtils.error("认证失败，或者密码错误 -> account:" + account + " password:" + password);
//                    MsgUtils.sendLoginFail(connection, SGCommonProto.E_LOGIN_RESULT.LOGIN_RESULT_FAIL, channel, recommendCamp);
//                    if(isDefault) GameServer.getInstance().getWorldManager().reduceCachePlayer();
//                    return;
//                }
                LogUtils.info("获取到user->", user);
                List<PlayerModel> playerModelList = playerService.getPlayerByUid(user.getId());
                LogUtils.info("获取到玩家数据列表->", playerModelList.size());
                PlayerModel playerModel = null;
                if(playerModelList != null){
                    if(playerModelList.size() == 1){
                        playerModel = playerModelList.get(0);
                    }else if(playerModelList.size() > 1){
                        List<PlayerModel> list = new ArrayList<>();
                        for(PlayerModel model : playerModelList)
                        {
                            if(!model.getIsDel())
                                list.add(model);
                        }
                        connection.setMergePlayers(list);
                        MsgUtils.sendLoginFailMergeServer(connection, list);
                        return;
                    }
                }
                if(playerModel == null)
                {
                    //数据异常，有账号没角色
                    LogUtils.error("数据异常，有账号没角色");
                    MsgUtils.sendLoginFail(connection, SGCommonProto.E_LOGIN_RESULT.LOGIN_RESULT_FAIL, channel, recommendCamp);
                    if(isDefault) GameServer.getInstance().getWorldManager().reduceCachePlayer();
                    return;
                }

                if(playerModel.getIsDel())
                {
                    LogUtils.error("玩家已被封号 -> " + playerModel.getName());
                    connection.sendWarn(WordFactory.LOCK_ACCOUNT);
                    MsgUtils.sendLoginFail(connection, SGCommonProto.E_LOGIN_RESULT.LOGIN_RESULT_FAIL, channel, recommendCamp);
                    return;
                }

                if(player == null)
                {
                    player = new Player(playerModel);//登陆完成后将玩家的 缓存玩家的钻石消耗数量
                    Map<E_QueryRechargeCountType,Integer> diamondsMap = GameServer.getInstance().getWorldManager().getDiamondsCache(TimeUtils.isToday(player.getLastLoginTime()),player);
                    player.getBonusData().setDiamondsCache(diamondsMap);

                    TwoTuple<Long, Long> inDayTime = CoreUtils.getTimeActivity();
                    playerService.queryTotalRechargeCount(player, inDayTime.getFirst(), inDayTime.getSecond());
                }
            }

            if(player == null || player.getId() == 0)
            {
                LogUtils.error("登录异常");
                MsgUtils.sendLoginFail(connection, channel);
                if(isDefault) GameServer.getInstance().getWorldManager().reduceCachePlayer();
                return;
            }

            if(player.isDel)
            {
                MsgUtils.sendLoginFail(connection, SGCommonProto.E_LOGIN_RESULT.LOGIN_RESULT_LOCK, channel, recommendCamp);
                if(isDefault) GameServer.getInstance().getWorldManager().reduceCachePlayer();
                return;
            }

            //正常登录才判断
            if(request.getNormal())
            {
//            int lockTime = playerService.getAccountLockTime(player.getId());
//            if(lockTime > 0)
//            {//还有这么多时间才解锁
//                response.setResult(E_Login_RESULT.Login_RESULT_Lock);
//                response.setChannel(channel);
//                response.setLockTime(lockTime/1000);//毫秒转为秒
//                connection.sendMsg(E_MSG_ID.MsgID_Login_VALUE, response.build().toByteArray());
//                return;
//            }
        }

            if(SGCommonProto.E_LOGIN_TYPE.LOGIN_TYPE_BATTLE_BACK != request.getLoginType())
            {
                //写入登录日志
                GameServer.getInstance().loginLog(channel, ip, player.objectIndex, request.getLoginType().name());
                //告知登录服务器，本次登录成功，方便登录服务器返回最近一次的登录服务器
                notifyAuthServerLoginSuccess(request.getAccount(), channel, player.objectIndex);
            }
        }
        LogUtils.info("准备enterGame->", player);
        enterGame(playerController, player, channel, request.getLoginType(),request.getServerRuleId(),request.getClientVersion());

        boolean isBattle = SGCommonProto.E_LOGIN_TYPE.LOGIN_TYPE_BATTLE_BACK == request.getLoginType();
        if(isBattle)
        {
            MsgUtils.addPlayerGoodsChange(E_MSG_ID.MsgID_War_SynResult_VALUE, playerController);
            SendUtils.sendChangeData(E_MSG_ID.MsgID_War_SynResult_VALUE, playerController);

            if(playerController.getWorldMapTaskCacheData() != null)
            {
                MsgUtils.sendWorldMapTaskChange(playerController, playerController.getWorldMapTaskCacheData());
                playerController.setWorldMapTaskCacheData(null);
            }

            if (playerController.getHegemonyScoreChangeBeanCache() != null)
            {
                SendUtils.sendHegemoneyChange(playerController, playerController.getHegemonyScoreChangeBeanCache());
                playerController.setHegemonyScoreChangeBeanCache(null);
            }

            if (playerController.getSendMsgCache() != null){
                SGSystemProto.S2C_NotifyAlert.Builder response = SGSystemProto.S2C_NotifyAlert.newBuilder();
                response.setType(SGCommonProto.E_NOTIFY_TYPE.NOTIFY_TYPE_WARN);
                response.setContent(playerController.getSendMsgCache()[0]);
                playerController.sendMsg(SGMainProto.E_MSG_ID.MsgID_System_NotifyAlert_VALUE,response.build().toByteArray());
                playerController.nullSendMsgCache();
            }

            //玩家战斗回来后通知玩家争霸赛变化信息
            if (playerController.getIsHegemonyCache() != null){
                if (playerController.isInWorldMap()){
                    SGMapProto.S2C_WorldMapIsHegemony.Builder response = SGMapProto.S2C_WorldMapIsHegemony.newBuilder();
                    response.setIsHegemony(playerController.getIsHegemonyCache()[0]);
                    playerController.sendMsg(E_MSG_ID.MsgID_WorldMap_IsHegemony_VALUE,response.build().toByteArray());
                }
                //在大地图才会推送  但是数据都要清除
                playerController.nullIsHegemonyCache();
            }
        }
        else
        {
            if(ActivityCampManager.getInstance().getStatus() != E_ActivityCampStatus.CLEAR_ING
                    && ActivityCampManager.getInstance().getStatus() != E_ActivityCampStatus.RUN_ING)
                //登录发放奖励
                player.getCampBattleData().checkReward(ActivityCampManager.getInstance().getIndex(), ActivityCampManager.getInstance().getCampRank(player.camp));
        }

//        MatchBaseInfo matchPlayer = ActivityCampManager.getInstance().getPlayer(player.getObjectIndex());
//        boolean isCampBattle = isBattle && playerController.getBattleData() != null && playerController.getBattleData().getBattleType() == SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_SPAN_CAMP && ActivityCampManager.getInstance().getStatus() == E_ActivityCampStatus.RUN_ING;
//        if(matchPlayer != null)
//        {
//            if(ServerManager.getInstance().getActivityServer() != null && ActivityCampManager.getInstance().getStatus() != E_ActivityCampStatus.CLEAR_ING)
//            {
//                if(isBattle && ActivityCampManager.getInstance().getStatus() == E_ActivityCampStatus.RUN_ING)
//                    ServerManager.getInstance().sendApplyActivity(player, E_ApplyCampActivityType.BATTLE_END);
//                else if(!isBattle)
//                    ServerManager.getInstance().sendApplyActivity(player, E_ApplyCampActivityType.LOGIN);
//            }
//        }
//        else
//        {
            if(ServerManager.getInstance().getActivityServer() != null && ActivityCampManager.getInstance().getStatus() != E_ActivityCampStatus.CLEAR_ING)
            {
//                if(player.getCampBattleData().applyCount > 0 && player.getCampBattleData().reviveCount >= 0)
//                {
                    if(player.getCampBattleData().activityIndex.equals(ActivityCampManager.getInstance().getIndex()))
                    {
//                        if(isBattle && ActivityCampManager.getInstance().getStatus() == E_ActivityCampStatus.RUN_ING)
//                            ServerManager.getInstance().sendApplyActivity(player, E_ApplyCampActivityType.BATTLE_END);
//                        else if(!isBattle)
//                            ServerManager.getInstance().sendApplyActivity(player, E_ApplyCampActivityType.LOGIN);
                    }
                    else
                        player.getCampBattleData().clearApplyData();
//                }
            }
//        }

    }


//    private UserModel getUser(SGCommonProto.E_CHANNEL_TYPE channel, String account, String password,PlayerService playerService) {
//        UserModel user = null;
//        LogUtils.info("登录平台id:" + channel);
//        switch (channel.getNumber()){
//            case SGCommonProto.E_CHANNEL_TYPE.CHANNEL_TYPE_QUICK_VALUE:
//                user = playerService.getUserByAccount(CoreUtils.createAccount(account, channel));
//                break;
//            case SGCommonProto.E_CHANNEL_TYPE.CHANNEL_TYPE_PHONE_VALUE:
//                user = SpringContext.getPlatformSDK(PhoneImpl.class).login(account, password);
//                break;
//            case SGCommonProto.E_CHANNEL_TYPE.CHANNEL_TYPE_QQ_VALUE:
//                user = SpringContext.getPlatformSDK(QQImpl.class).login(account, password);
//                break;
//            case SGCommonProto.E_CHANNEL_TYPE.CHANNEL_TYPE_YJ_VALUE:
//                user = SpringContext.getPlatformSDK(YjImpl.class).login(account, password);
//                break;
////            case SGCommonProto.E_CHANNEL_TYPE.CHANNEL_TYPE_WECHAT_VALUE:
////                user = SpringContext.getPlatformSDK(WeChatImpl.class).login(account, password);
//            case SGCommonProto.E_CHANNEL_TYPE.CHANNEL_TYPE_QIANGWAN_VALUE:
//                user = SpringContext.getPlatformSDK(QWImpl.class).login(account, password);
//                break;
//            case SGCommonProto.E_CHANNEL_TYPE.CHANNEL_TYPE_JITUO_VALUE:
//                user = SpringContext.getPlatformSDK(JTImpl.class).login(account, password);
//                break;
//            case SGCommonProto.E_CHANNEL_TYPE.CHANNEL_TYPE_PINGPING_VALUE:
//                user = SpringContext.getPlatformSDK(PPImpl.class).login(account, password);
//                break;
//            case SGCommonProto.E_CHANNEL_TYPE.CHANNEL_TYPE_QUICKSDK_VALUE:
//                user = SpringContext.getPlatformSDK(QuickSDKImpl.class).login(account, password);
//                break;
//
//        }
//        return user;
//    }

    private void enterGame(PlayerController playerController, Player player, SGCommonProto.E_CHANNEL_TYPE channel, SGCommonProto.E_LOGIN_TYPE loginType,
                           int serverRuleId,String clientVersion)
    {
        PlayerService playerService = SpringContext.getBean(PlayerService.class);
        try{
            playerService.enterGame(playerController, player, channel, loginType,serverRuleId,clientVersion, connection);
        }catch (Exception e){
            e.printStackTrace();
            connection.setObject(null);
        }
    }

    private void notifyAuthServerLoginSuccess(String account, SGCommonProto.E_CHANNEL_TYPE channel, String objectIndex) {
        //注册
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("serverId", GameServer.getInstance().getServerId());
        jsonObject.put("channel", channel.getNumber());
        jsonObject.put("account", CoreUtils.createAccount(account, channel));
        jsonObject.put("objectIndex", objectIndex);
        long t1 = System.currentTimeMillis();
        JSONObject result = HttpJsonUtils.httpPost(GameServer.getInstance().getAuthServerHost() + HttpFactory.PLAYER_LOGIN_SUCCESS, jsonObject);
        long t2 = System.currentTimeMillis();
        LogUtils.info("请求认证服登录成功耗时->", t2 - t1);
    }

    /**
     * 注册
     * @param byteBuf
     */
    private void register(ByteBuf byteBuf, String ip) {
        byte[] data = CoreUtils.byteBufToBytes(byteBuf);
        SGSystemProto.C2S_Regist request = null;
        try {
            request = SGSystemProto.C2S_Regist.parseFrom(data);
        } catch (InvalidProtocolBufferException e) {
            e.printStackTrace();
        }
        if(request == null){
            LogUtils.error("数据异常 request is null");
            connection.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        //合区的时候要验证一些数据
        if (request.getServerRuleId() <= 0){
            LogUtils.error("数据异常,serverRuleId:" + request.getServerRuleId());
            connection.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }

        if (StringUtils.isNullOrEmpty(request.getClientVersion())){
            LogUtils.error("数据异常,clientVersion is null");
            connection.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        LogUtils.info("注册参数:\n" + request.toString());
        if(StringUtils.isNullOrEmpty(request.getNickName())){
            LogUtils.info("昵称为空了");
            connection.sendWarn(WordFactory.NAME_NOT_EMPTY);
            return;
        }
        if(request.getNickName().length() > ConstantFactory.NAME_MAX_LENGTH){
            LogUtils.info("昵称过长: " + request.getNickName());
            connection.sendWarn(WordFactory.NAME_TOO_LONG);
            return;
        }
        if (StringUtils.isNullOrEmpty(request.getClientVersion())){
            LogUtils.info("clientVersion null" );
            connection.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        LogUtils.debug("clientVersion :" + request.getClientVersion());

        if (StringUtils.isNullOrEmpty(request.getOsversion())){
            LogUtils.info("osversion null" );
            connection.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        LogUtils.debug("osversion :" + request.getOsversion());

        if (StringUtils.isNullOrEmpty(request.getTdid())){
            LogUtils.info("tdid null");
            connection.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        LogUtils.debug("tdid :" + request.getTdid());

        if (StringUtils.isNullOrEmpty(request.getTdDeviceId())){
            LogUtils.info("tdDeviceId null ");
            connection.sendWarn(WordFactory.PARAM_ERROR);
            return;
        }
        LogUtils.debug("tdDeviceId :" + request.getTdDeviceId());

        //提交到认证服务器去记录角色
        String result = createRoleRecord(ip, request, request.getCampValue(), "", true);
        if(StringUtils.isNullOrEmpty(result)){
            //注册信息认证成功，进行注册
            PlayerService playerService = SpringContext.getBean(PlayerService.class);
            String newAccount = PlatformFactory.auth(request.getChannel(), request.getAccount(), request.getPassword());
            if(Utils.isNullOrEmpty(newAccount))
            {
                LogUtils.info("认证失败，或者密码错误");
                connection.sendWarn(WordFactory.PARAM_ERROR);
                return;
            }

//            UserModel user  = playerService.getUserByAccount(newAccount);
//            if(user != null && user.getId() == 0)
//            { //认证失败
//                LogUtils.info("认证失败，或者密码错误");
//                connection.sendWarn(WordFactory.PARAM_ERROR);
//                return;
//            }
            UserModel user = null;
            //验证本服务器上账户是否存在
            if(request.getChannel() == SGCommonProto.E_CHANNEL_TYPE.CHANNEL_TYPE_QUICK){
                user = playerService.getUserByAccount(CoreUtils.createAccount(newAccount, request.getChannel()));
            }else {
                user = playerService.getUserByAccount(CoreUtils.createAccount(newAccount, request.getChannel()));
            }


            if(user != null)
            {
                LogUtils.info("账户已存在");
                connection.sendWarn(WordFactory.ACCOUNT_EXIST);
                return;
            }

            SGCommonProto.E_CAMP_TYPE campType = request.getCamp();
            campType = (SGCommonProto.E_CAMP_TYPE.CAMP_TYPE_UNKNOWN == campType || campType == null) ? SGCommonProto.E_CAMP_TYPE.CAMP_TYPE_BRIGHT : campType;

            Player player = playerService.regist(request.getAccount(), request.getNickName(), request.getPassword(), request.getAvatarUrl(), request.getChannel(), campType, ip);

            createRoleRecord(ip, request, campType.getNumber() ,player.objectIndex, false);
            notifyAuthServerLoginSuccess(request.getAccount(), request.getChannel(), player.objectIndex);
            //使用的是推荐郑营
            if(request.getIsRandomRole() && recommendCamp != null && request.getCamp() != null && recommendCamp == campType ){
                StableDataConfig stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.RANDOM_CAMP_REWARD.getCode());
                if(stableDataConfig != null){
                    MailConfig mailConfig = DataFactory.getInstance().getGameObject(DataFactory.MAIL_MODEL_KEY, E_MailModelType.RANDOM_CAMP.getCode());
                    List<GoodsData> list = new ArrayList<>();
                    list.add(stableDataConfig.goods[0]);
                    MailDB mailDB = new MailDB(mailConfig.title, MessageFormat.format(mailConfig.content, stableDataConfig.goods[0].value), list);
                    MailInfo mailInfo = player.getExtInfo(MailInfo.class);
                    mailInfo.addMail(SGCommonProto.E_MAIL_TYPE.MAIL_TYPE_SYSTEM_VALUE, mailDB);
                }
            }

            //获取已注册用户
//            List<Compensate> list = LoadFactory.compensateList();
//            MailInfo mailInfo = player.getExtInfo(MailInfo.class);
//            String title = "";
//            String content = "";
//            int money = 0;
//            int diamonds = 0;
//            List<GoodsData> goodsDatas = null;
//            MailConfig mailConfig = DataFactory.getInstance().getGameObject(DataFactory.MAIL_MODEL_KEY, E_MailModelType.DOUBLE_RECHARGE.getCode());
//            if(mailConfig != null){
//                 title = mailConfig.title;
//                 content = mailConfig.content;
//            }
//
//            final long currentTime = System.currentTimeMillis();
//            for (Compensate compensate : list ){
//                if(compensate.getAccount().equals(player.getAccount())){
//                    goodsDatas = new ArrayList<>();
//                    money = compensate.getMoney();
//                    diamonds = compensate.getMoney() * 20;
//                    goodsDatas.add(new GoodsData(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_ASSETS_VALUE, ConfigFactory.ASSET_MONEY_KEY, diamonds));
//                    mailInfo.addMail(SGCommonProto.E_MAIL_TYPE.MAIL_TYPE_SYSTEM_VALUE,title,MessageFormat.format(content, money, diamonds), E_MailSenderType.MAIL_TYPE_RECEIVER.getCode(),player.getObjectIndex(),goodsDatas,DataFactory.currentTime);
//
//                    FixDBUtils.fixVip(player, money, currentTime);
//
//                    LogUtils.warn("新注册用户获得上次测试充值双倍返还钻石 -> 昵称:" + player.getName() + " -> 返还钻石:" + diamonds);
//                    break;
//                }
//            }

            SGSystemProto.S2C_Regist.Builder response = SGSystemProto.S2C_Regist.newBuilder();
            response.setResult(SGCommonProto.E_REGIST_RESULT.REGIST_RESULT_Success);
            response.setResourceUrl("123");
            response.setPassword("123");

            SGCommonProto.PlayerBaseInfo.Builder baseInfo = SGCommonProto.PlayerBaseInfo.newBuilder();
            baseInfo.setNickName(player.getName());
            baseInfo.setPlayerIndex(player.getObjectIndex());
            baseInfo.setAvatar(player.avatar);
            baseInfo.setMobile(player.getMobile());
            baseInfo.setFc(player.fc);
            baseInfo.setExp(player.getExp());
            baseInfo.setLv(player.getLv());
            baseInfo.setVipLv(player.getVipLevel());
            response.setPlayerInfo(baseInfo);

            connection.sendMsg(E_MSG_ID.MsgID_System_Regist_VALUE, response.build().toByteArray());

            enterGame(null, player, request.getChannel(), SGCommonProto.E_LOGIN_TYPE.LOGIN_TYPE_DEFAULT, request.getServerRuleId(), request.getClientVersion());
            return;
        }
        else
        {
            connection.sendWarn(result);
            return;
        }
    }

    private String createRoleRecord(String ip, SGSystemProto.C2S_Regist c2S_regist, int defaultAvatar, String objectIndex, boolean justCheck) {
        //注册
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("serverId", GameServer.getInstance().getServerId());
        jsonObject.put("channel", c2S_regist.getChannel().getNumber());
        if(c2S_regist.getChannel() == SGCommonProto.E_CHANNEL_TYPE.CHANNEL_TYPE_QUICK){
            jsonObject.put("deviceId", c2S_regist.getAccount());
        }else {
            jsonObject.put("account", c2S_regist.getAccount());
        }

        jsonObject.put("password", c2S_regist.getPassword());
        jsonObject.put("ip", ip);
        jsonObject.put("playName", c2S_regist.getNickName());
        jsonObject.put("avatar", StringUtils.isNullOrEmpty(c2S_regist.getAvatarUrl()) ? defaultAvatar : c2S_regist.getAvatarUrl());
        jsonObject.put("level", 1);
        jsonObject.put("objectIndex", objectIndex);
        jsonObject.put("justCheck", justCheck);
        jsonObject.put("serverRuleId",c2S_regist.getServerRuleId());
        jsonObject.put("clientVersion",c2S_regist.getClientVersion());
        jsonObject.put("osversion",c2S_regist.getOsversion());
        jsonObject.put("tdid",c2S_regist.getTdid());
        jsonObject.put("tdDeviceIdType",c2S_regist.getTdDeviceIdTypeValue());
        jsonObject.put("tdDeviceId",c2S_regist.getTdDeviceId());
        JSONObject result = HttpJsonUtils.httpPost(GameServer.getInstance().getAuthServerHost() + HttpFactory.PLAYER_REGISTER, jsonObject);
        if(result == null || !result.containsKey("code"))
        {
            LogUtils.error("创建角色提交认证服务器失败 -> " + GameServer.getInstance().getAuthServerHost());
            return WordFactory.PARAM_ERROR;
        }
        String resultCode = result.getString("code");
        if(Integer.parseInt(resultCode) == 0){//成功
            return null;
        }else {
            if(resultCode.equals(ReturnMessage.NICKNAME_EXITS.getCode())){
                return WordFactory.NAME_EXIST;
            } else if(resultCode.equals(ReturnMessage.THIS_SERVER_PLAYER_EXITS.getCode())){
                return WordFactory.ACCOUNT_EXIST;
            }else {
                LogUtils.error("注册错误1 -> " + GameServer.getInstance().getAuthServerHost());
                LogUtils.error("注册错误2 -> " + resultCode);
                return WordFactory.PARAM_ERROR;
            }
        }
//        return s2CRegist;
    }


    /*
     * channelReadComplete
     *
     * channel  通道
     * Read     读取
     * Complete 完成
     *
     * 在通道读取完成后会在这个方法里通知，对应可以做刷新操作
     * ctx.flush()
     *
     */
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    /*
     * exceptionCaught
     *
     * exception	异常
     * Caught		抓住
     *
     * 抓住异常，当发生异常的时候，可以做一些相应的处理，比如打印日志、关闭链接
     *
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception
    {
        try{
            if(cause.getClass() != IOException.class)
            {
                cause.printStackTrace();
                close();
            }

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public int isForbid(Player player,int msgId,byte[] data) {
        int functionId = 0;
        switch (msgId) {
            case E_MSG_ID.MsgID_Pub_LotteryInit_VALUE:
            case E_MSG_ID.MsgID_Pub_LotteryClick_VALUE:
                functionId = FunctionFactory.UNLOCK_LOTTERY;
                break;

            case E_MSG_ID.MsgID_Instance_ReceiveAward_VALUE:
            case E_MSG_ID.MsgID_Instance_RequestLevelBattle_VALUE:
            case E_MSG_ID.MsgID_Instance_ReceiveLevelBoxReward_VALUE:
                functionId = FunctionFactory.UNLOCK_REPLICA_SYSTEM;
                break;

            case E_MSG_ID.MsgID_Arena_GetArenaInfo_VALUE:
            case E_MSG_ID.MsgID_Arena_Challenge_VALUE:
            case E_MSG_ID.MsgID_Arena_GetDailyReward_VALUE:
            case E_MSG_ID.MsgID_Arena_PreviewRank_VALUE:
            case E_MSG_ID.MsgID_Arena_ExchangeReward_VALUE:
            case E_MSG_ID.MsgID_Arena_RewardRecord_VALUE:
            case E_MSG_ID.MsgID_Arena_Sweep_VALUE:
                functionId = FunctionFactory.UNLOCK_COMPETITIVE_SYSTEM;
                break;

            case E_MSG_ID.MsgID_Altar_Init_VALUE:
                functionId = FunctionFactory.UNLOCK_ALTAR_SYSTEM;
                break;

            case E_MSG_ID.MsgID_OfficialWar_InitInfo_VALUE:
            case E_MSG_ID.MsgID_OfficialWar_PreviewRank_VALUE:
            case E_MSG_ID.MsgID_OfficialWar_ChallengeRank_VALUE:
            case E_MSG_ID.MsgID_OfficialWar_SweepRank_VALUE:
            case E_MSG_ID.MsgID_OfficialWar_GetDailyReward_VALUE:
            case E_MSG_ID.MsgID_OfficialWar_ExchangeReward_VALUE:
            case E_MSG_ID.MsgID_OfficialWar_RewardRecord_VALUE:
            case E_MSG_ID.MsgID_OfficialWar_IntegralReward_VALUE:
            case E_MSG_ID.MsgID_OfficialWar_IntegralRewardRecord_VALUE:
            case E_MSG_ID.MsgID_OfficialWar_RequestBattle_VALUE:
                functionId = FunctionFactory.UNLOCK_Military_SYSTEM;
                break;

            case E_MSG_ID.MsgID_Task_TaskList_VALUE:
            case E_MSG_ID.MsgID_Task_TaskReward_VALUE:
            case E_MSG_ID.MsgID_Task_TreasureReward_VALUE:
                try{
                    int type = 0;
                    if(E_MSG_ID.MsgID_Task_TaskList_VALUE == msgId)
                    {
                        type = SGTaskProto.C2S_TaskList.parseFrom(data).getType().getNumber();
                    }
                    else if(E_MSG_ID.MsgID_Task_TaskReward_VALUE == msgId)
                    {
                        TaskConfig taskConfig = DataFactory.getInstance().getGameObject(DataFactory.TASK_KEY, SGTaskProto.C2S_TaskReward.parseFrom(data).getTaskId());
                        type = taskConfig == null ? 0 : taskConfig.type;
                    }
                    else
                    {
                        type = SGTaskProto.C2S_TreasureReward.parseFrom(data).getType().getNumber();
                    }
                    if(type == SGCommonProto.E_TASK_TYPE.TASK_TYPE_MAIN_LINE_VALUE || type == SGCommonProto.E_TASK_TYPE.TASK_TYPE_BRANCH_LINE_VALUE)
                        functionId = FunctionFactory.UNLOCK_MAIN_TASK;
                    else if(type == SGCommonProto.E_TASK_TYPE.TASK_TYPE_EVERYDAY_VALUE)
                        functionId = FunctionFactory.UNLOCK_EVERY_TASK;
                }catch (Exception e){
                    e.printStackTrace();
                }
                break;

            case E_MSG_ID.MsgID_Store_InitInfo_VALUE:
                try {
                    SGPlayerProto.C2S_StoreInitInfo store = SGPlayerProto.C2S_StoreInitInfo.parseFrom(data);
                    if (store.getType().getNumber() == SGCommonProto.E_STORE_TYPE.STORE_TYPE_GOBLIN_VALUE) {
                        functionId = FunctionFactory.UNLOCK_GOBLIN_SHOP_SYSTEM;
                    }else if (store.getType().getNumber() == SGCommonProto.E_STORE_TYPE.STORE_TYPE_ARENA_VALUE) {
                        functionId = FunctionFactory.UNLOCK_ARENA_SHOP_SYSTEM;
                    }else if (store.getType().getNumber() == SGCommonProto.E_STORE_TYPE.STORE_TYPE_EQUIP_VALUE) {
                        functionId = FunctionFactory.UNLOCK_EQUIPMENT_MATERIAL_SHOP_SYSTEM;
                    }else if(store.getType().getNumber() == SGCommonProto.E_STORE_TYPE.STORE_TYPE_EXPEDITION_VALUE){
                        functionId = FunctionFactory.UNLOCK_EXPEDITION_SYSTEM;
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
                break;
            case E_MSG_ID.MsgID_Store_BuyGoods_VALUE:
                try {
                    SGPlayerProto.C2S_StoreBuyGoods storeBuyGoods = SGPlayerProto.C2S_StoreBuyGoods.parseFrom(data);
                    if (storeBuyGoods.getType().getNumber() == SGCommonProto.E_STORE_TYPE.STORE_TYPE_GOBLIN_VALUE) {
                        functionId = FunctionFactory.UNLOCK_GOBLIN_SHOP_SYSTEM;
                        break;
                    }else if (storeBuyGoods.getType().getNumber() == SGCommonProto.E_STORE_TYPE.STORE_TYPE_ARENA_VALUE) {
                        functionId = FunctionFactory.UNLOCK_ARENA_SHOP_SYSTEM;
                        break;
                    }else if (storeBuyGoods.getType().getNumber() == SGCommonProto.E_STORE_TYPE.STORE_TYPE_EQUIP_VALUE) {
                        functionId = FunctionFactory.UNLOCK_EQUIPMENT_MATERIAL_SHOP_SYSTEM;
                        break;
                    }else if(storeBuyGoods.getType().getNumber() == SGCommonProto.E_STORE_TYPE.STORE_TYPE_EXPEDITION_VALUE){
                        functionId = FunctionFactory.UNLOCK_EXPEDITION_SYSTEM;
                        break;
                    }

                } catch (InvalidProtocolBufferException e) {
                    e.printStackTrace();
                }
                break;

            case E_MSG_ID.MsgID_Bag_RebirthCard_VALUE:
            case E_MSG_ID.MsgID_Bag_ResolveCardPreview_VALUE:
            case E_MSG_ID.MsgID_Bag_SoulResolve_VALUE:
            case E_MSG_ID.MsgID_Bag_EquipResolve_VALUE:
                functionId = FunctionFactory.UNLOCK_RENASCENCE_SANCTUARY;
                break;

            case E_MSG_ID.MsgID_Bag_CardDetail_VALUE:
                functionId = FunctionFactory.UNLOCK_CARD_DETAIL;
                break;
            case E_MSG_ID.MsgID_Bag_CardUpLv_VALUE:
                functionId = FunctionFactory.UNLOCK_CARD_UP_LV;
                break;

            case E_MSG_ID.MsgID_Bag_CardUpStar_VALUE:
                functionId = FunctionFactory.UNLOCK_CARD_UP_STAR;
                break;

            case E_MSG_ID.MsgID_Bag_CardFate_VALUE:
            case E_MSG_ID.MsgID_Bag_CardFateList_VALUE:
                functionId = FunctionFactory.UNLOCK_CARD_FATE;
                break;

            case E_MSG_ID.MsgID_Bag_EquipIntensify_VALUE:
                functionId = FunctionFactory.UNLOCK_EQUIP_INTENSIFY;
                break;
            case E_MSG_ID.MsgID_Bag_EquipUp_VALUE:
                functionId = FunctionFactory.UNLOCK_EQUIP_SYN;
                break;

            case E_MSG_ID.MsgID_Bag_AccessoryIntensify_VALUE:
                functionId = FunctionFactory.UNLOCK_ACCESSORY_ACTIVATION_UP_LV;
                break;

            case E_MSG_ID.MsgID_Bag_AccessoryUp_VALUE:
                functionId = FunctionFactory.UNLOCK_ACCESSORY_UP_LV;
                break;
            case E_MSG_ID.MsgID_HeroTemple_InitInfo_VALUE:
            case E_MSG_ID.MsgID_HeroTemple_Challenge_VALUE:
            case E_MSG_ID.MsgID_HeroTemple_Sweep_VALUE:
                functionId = FunctionFactory.UNLOCK_HEROIC_SANCTUARY;
                break;
            case E_MSG_ID.MsgID_Expedition_Init_VALUE:
            case E_MSG_ID.MsgID_Expedition_ChallengeRequest_VALUE:
            case E_MSG_ID.MsgID_Expedition_FreshBoss_VALUE:
            case E_MSG_ID.MsgID_Expedition_CallBoss_VALUE:
                functionId = FunctionFactory.UNLOCK_EXPEDITION_SYSTEM;
                break;
            case E_MSG_ID.MsgID_Player_MasterTrain_VALUE:
            case E_MSG_ID.MsgID_Player_MasterTrainAccept_VALUE:
                functionId = FunctionFactory.UNLOCK_MASTER_TRIAN;
                break;
            case E_MSG_ID.MsgID_Major_Battle_VALUE:
            case E_MSG_ID.MsgID_Major_CollectInit_VALUE:
            case E_MSG_ID.MsgID_Major_CollectRevengeList_VALUE:
            case E_MSG_ID.MsgID_Major_CollectStart_VALUE:
            case E_MSG_ID.MsgID_Major_CollectProductionReceiver_VALUE:
                functionId = FunctionFactory.UNLOCK_MAJOR_COLLECT;
                break;
            case E_MSG_ID.MsgID_Major_MergeInit_VALUE:
            case E_MSG_ID.MsgID_Major_Merge_VALUE:
                functionId = FunctionFactory.UNLOCK_MAJOR_REFINING;
                break;
            case E_MSG_ID.MSGID_Mall_InitInfo_VALUE:
                try {
                    SGPlayerProto.C2S_MallInitInfo store = SGPlayerProto.C2S_MallInitInfo.parseFrom(data);
                    if (store.getMallType()== SGCommonProto.E_MALL_TYPE.MALL_TYPE_DIAMOND) {
                        functionId = FunctionFactory.MALL_DIAMOND;
                    }else if (store.getMallType()== SGCommonProto.E_MALL_TYPE.MALL_TYPE_VIP) {
                        functionId = FunctionFactory.MALL_VIP;
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
                break;
            case E_MSG_ID.MSGID_Mall_Buy_VALUE:
                try {
                    SGPlayerProto.C2S_MallBuy storeBuyGoods = SGPlayerProto.C2S_MallBuy.parseFrom(data);
                    MallConfig config = DataFactory.getInstance().getGameObject(DataFactory.MALL_STORE_KEY, storeBuyGoods.getGoodsId());
                    if(config != null){
                        if (config.sortType == SGCommonProto.E_MALL_TYPE.MALL_TYPE_DIAMOND_VALUE) {
                            functionId = FunctionFactory.MALL_DIAMOND;
                            break;
                        }else if (config.sortType == SGCommonProto.E_MALL_TYPE.MALL_TYPE_VIP_VALUE) {
                            functionId = FunctionFactory.MALL_VIP;
                            break;
                        }
                    }

                } catch (InvalidProtocolBufferException e) {
                    e.printStackTrace();
                }
                break;
            case E_MSG_ID.MsgID_WorldBossInit_VALUE:
                functionId = FunctionFactory.WORLD_BOSS;
                break;
        }

        if(!CoreUtils.isFunctionUnLock(functionId,player)){
            return functionId;
        }
        return 0;
    }

    public NettyConnection getConnection()
    {
        return connection;
    }

    public static void mergrReady() {
        isMerge = true;
    }
}
